%include	"pm.inc"

	org	0100h
	jmp LABEL_BEGIN

[section .gdt]
	; 					段描述符	段基址		段界限			段属性
	LABEL_GDT:			Descriptor	0, 			0, 				0
	LABEL_DESC_CODE32:	Descriptor	0,			code32Len-1,	DA_32 + DA_C
	LABEL_DESC_VIDEO:	Descriptor	0B8000h,	0ffffh,			DA_DRW
	gdtLen	equ $-LABEL_GDT
	gdtPtr	dw	gdtLen-1
			dd	0
			
	code32Selector	equ LABEL_DESC_CODE32 - LABEL_GDT
	videoSelector	equ LABEL_DESC_VIDEO - LABEL_GDT
		
[section .s16]
[bits 16]		
LABEL_BEGIN:
	mov	ax, cs
	mov ds, ax
	mov es, ax
	mov ss, ax
	mov sp, 0100h
	
	; 32位代码段描述符初始化
	xor eax, eax
	mov ax, cs
	shl eax, 4
	add eax, LABEL_CODE32
	mov word [LABEL_DESC_CODE32 + 2], ax
	shr eax, 16
	mov byte [LABEL_DESC_CODE32 + 4], al
	mov byte [LABEL_DESC_CODE32 + 7], ah
	
	; GDT 基址初始化
	xor eax, eax
	mov ax, ds
	shl eax, 4
	add eax, LABEL_GDT
	mov dword [gdtPtr + 2], eax

	; GDT 加载
	lgdt [gdtPtr]
	
	; 关闭中断
	cli
	
	; 打开A20地址线
	in al, 92h
	or al, 00000010b
	out 92h, al
	
	; 切换到保护模式
	mov eax, cr0
	or eax, 1
	mov cr0, eax
	
	jmp dword code32Selector:0
	

[section .s32]
[bits 32]
LABEL_CODE32:
	mov ax, videoSelector
	mov gs, ax
	mov edi, (80 * 11 + 79) * 2
	mov ah, 0x0c
	mov al, 'P'
	mov [gs:edi], ax
	jmp $
code32Len	equ	$-LABEL_CODE32